import random
import time
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
import logging
import requests
import json

# 代理
proxies = {
    'http': '127.0.0.1:7890',
    'https': '127.0.0.1:7890'
}
# 定义日志
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(levelname)s: %(message)s')


def generate_session_id(prefix="sssgram", length=10, ts=None):
    """
    通过时间戳生成session_id
    :param prefix:
    :param length:
    :param ts:
    :return:
    """
    chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    rand_str = ''.join(random.choices(chars, k=length))
    if ts is None:
        ts = int(time.time() * 1000)  # 毫秒级时间戳
    return f"{prefix}_{rand_str}_{ts}"


def encrypt_with_public_key(plaintext: str) -> str:
    """
    通过时间戳生成加密数据，用于Header中 X-Secure-Message参数
    :param plaintext:
    :return:
    """
    public_key = (
        "-----BEGIN PUBLIC KEY-----\n"
        "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCAdf/EyIbLBxjGqmh7qLU6/CPCzru+75+82OSPZ+nf4BFvg88drpZ6KigNW0J8TNgxe6Yms1irCZNVDyu+RXsl4y/7c2KOHc4OGTzHB5fUMiMasFUvcEs2P70e6yA/sKHZfBLG1XPhlb84Ibs3nhD3W5e2SuC+4EuVkaqzN08LQIDAQAB\n"
        "-----END PUBLIC KEY-----"
    )

    rsa_key = RSA.import_key(public_key)
    cipher = PKCS1_v1_5.new(rsa_key)

    encrypted_bytes = cipher.encrypt(plaintext.encode('utf-8'))
    encrypted_base64 = base64.b64encode(encrypted_bytes).decode('utf-8')
    return encrypted_base64


def parse_get_data(dict_obj, session_id):
    """
    解析接口返回的dict数据，加工处理返回带有可访问资源链接的json数据
    :param dict_obj:
    :param session_id:
    :return:
    """
    result = None
    dict_obj_result = dict_obj.get('result')
    if dict_obj_result:
        insBos = dict_obj_result.get('insBos')
        cl_insBos = []  # 处理之后的insBos
        for data in insBos:
            item = {}
            for key, value in data.items():
                item[key] = value
                # 找到cover、url、thumb 拼接有效链接，替换原值
                if key == 'cover' or key == 'url' or key == 'thumb':
                    resource_url = f"https://api.sssgram.com/st-tik/token/{value}?sessionid={session_id}&wh=www.sssgram.com"
                    item[key] = resource_url
            cl_insBos.append(item)
        # print(cl_insBos)
        # 修改原dict的 insBos
        dict_obj['result']['insBos'] = cl_insBos
    # print(dict_obj)
    # 处理并返回json
    result = json.dumps(dict_obj, ensure_ascii=False, indent=2)
    return result



def api_ajax(url):
    """
    根据目标站点链接，站点名称，返回解析的资源
    :param link_url: 站点链接
    :param method: 请求方式 默认POST
    :return:
    """

    # 毫秒级当前时间戳
    time_ts = time.time_ns() // 1_000_000
    # 根据时间戳生成session_id
    session_id = generate_session_id(prefix="sssgram", length=12, ts=time_ts)
    x_secure_message = encrypt_with_public_key(str(time_ts))

    data = {
        'url': url,
        'sessionid': session_id
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
        'X-Secure-Message': x_secure_message,
        'Referer': 'https://www.sssgram.com/'
    }
    result = None
    logging.info('开始请求url, url: %s', url)
    try:
        # 发出请求
        response = requests.request('GET', url='https://api.sssgram.com/st-tik/ins/dl', params=data, headers=headers,
                                    proxies=proxies)
        # 响应成功
        if response.status_code == 200:
            # 返回的字典数据
            dict_obj = response.json()
            # 解析数据返回可用的json数据
            result = parse_get_data(dict_obj, session_id)
            return result
        logging.error('请求状态码错误, code: %s', response.status_code)
    except requests.RequestException as e:
        logging.error('请求链接报错，url: %s', url, exc_info=True)


# 示例调用
if __name__ == "__main__":
    # # 调用示例
    # custom_ts = time.time_ns() // 1_000_000
    # sid2 = generate_session_id(prefix="sssgram", length=12, ts=custom_ts)
    # print(sid2)
    #
    # # 也是用相同毫秒时间戳生成
    # enc = encrypt_with_public_key(str(custom_ts))
    # print(enc)

    res = api_ajax('https://www.instagram.com/p/DK7SPUFpbGz/?utm_source=ig_web_copy_link')
    print(res)
